#ifndef __USERDEF_H__
#define __USERDEF_H__
#include "fw_hal.h"

#ifdef EXTRN
	#undef EXTRN
#endif

#ifdef HERE_EXEC
	#define	EXTRN
	#define	INIT_END	1
#else
	#define	EXTRN extern
	#define	INIT_END	0
#endif

#define WITHIN(N,L,H)       ((N) >= (L) && (N) <= (H))
#define _MIN(x,y) ((x)<(y)?(x):(y))
#define _MAX(x,y) ((x)<(y)?(y):(x))

#define _SHIFT(XXX,YYY) ((XXX)>>(YYY))
#define _REMAINDER(XXX,YYY)	((XXX)-(_SHIFT((XXX),(YYY))<<(YYY)))

#define SYS_TICK 1000

EXTRN  uint32_t code MaskBits[32]
#if INIT_END
= {
	0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
	(0x1UL << 8), (0x1UL << 9), (0x1UL << 10), (0x1UL << 11),
	(0x1UL << 12), (0x1UL << 13), (0x1UL << 14), (0x1UL << 15),
	(0x1UL << 16), (0x1UL << 17), (0x1UL << 18), (0x1UL << 19),
	(0x1UL << 20), (0x1UL << 21), (0x1UL << 22), (0x1UL << 23),
	(0x1UL << 24), (0x1UL << 25), (0x1UL << 26), (0x1UL << 27),
	(0x1UL << 28), (0x1UL << 29), (0x1UL << 30), (0x1UL << 31),
}
#endif
;

typedef void (*fun_)(uint8_t,int32_t) reentrant;
typedef struct
{
	fun_     p_fun;
  uint32_t nLine;
	int32_t  nStep;
	uint32_t bTick;
  uint8_t  lock;
}type_fun;

#define SIZE_FUN 20
EXTRN type_fun xdata SuperFun[SIZE_FUN];

#define crBegin(_id,_Step) {SuperFun[_id].nStep -=_Step;\
        if(SuperFun[_id].nStep>0)return; switch(SuperFun[_id].nLine){ case 0:

#define crReturn(_id) do{ SuperFun[_id].nLine=__LINE__;return; case __LINE__:;}while(0)
#define crWait(_id,nTick) SuperFun[_id].nStep=nTick;crReturn(_id)
#define crFinish(_id)  SuperFun[_id].nLine=0;}}
#define crDel(_id) do{SuperFun[_id].nLine=0;SuperFun[_id].nStep=0;SuperFun[_id].p_fun=NULL;}while(0)
#define crAgain(_id) do { SuperFun[_id].nLine=0; return;}while(0)
#define crEnd()  }}
#define crLock(_id) SuperFun[_id].lock=1
#define crUnlock(_id) SuperFun[_id].lock=0

void task_init(void);
uint8_t task_get(fun_ p_fun_name);
void task_del(fun_ p_fun_name);
void task_exec(void);
void task_del_other(fun_ p_fun_name);

void task_debub(uint8_t id,int32_t ntick) reentrant;

typedef enum {DIR_CW= 0,DIR_CCW= 1} dir_enum_t;
typedef enum {ENABMOTOR= 0,DISMOTOR= 1} en_enum_t;
typedef enum {STA_STOP= 0,STA_ACC= 1,STA_AVG= 2,STA_DEC= 3,STA_IDLE =4} state_enum_t;

typedef enum {_M_OTHER= 0,_M_TD= 1} e_menu_state_t;
EXTRN  e_menu_state_t menu_state
#if INIT_END
=_M_OTHER
#endif
;

typedef struct
{
	volatile uint8_t dir;

	volatile uint32_t step_spmax;
	volatile uint32_t step_spmix;
	
	volatile uint32_t step_accel;
	volatile uint32_t step_speed;
	volatile uint32_t step_state;
	
	volatile uint32_t ntick;
	volatile uint32_t wtick;
	
	volatile uint32_t accel_ticks;

  volatile uint8_t  e_stop;	
}motor_control_t;
EXTRN motor_control_t xdata motor_control
#if INIT_END
={0,}
#endif
;

EXTRN volatile uint32_t sys_tick
#if INIT_END
=0
#endif
;

EXTRN volatile int16_t encoder_diff
#if INIT_END
=0
#endif
;

EXTRN uint32_t cure_time
#if INIT_END
=60
#endif
;

EXTRN uint32_t wash_time
#if INIT_END
=30
#endif
;

EXTRN uint32_t down_time
#if INIT_END
=10
#endif
;

#define DOWN_CMD_MAX 6
EXTRN  uint8_t code down_cmd[DOWN_CMD_MAX]
#if INIT_END
= {0xaa,0xb1,0xb2,0xb3,0xb4,0xb5}
#endif
;

//menu def and macros
typedef struct 
{
	const uint16_t x_size;
	const uint16_t y_size;
	uint8_t *dat;
} bmp_map_t;


//motor macros
#define MOTOR_STP           P35
#define MOTOR_STP_INIT()    GPIO_P3_SetMode(GPIO_Pin_5,GPIO_Mode_Output_PP);GPIO_SetSwitchSpeed(P3,GPIO_Pin_5,GPIO_SwitchSpeed_High);GPIO_SetPullUp(P3,GPIO_Pin_5,1)

#define MOTOR_EN            P36
#define MOTOR_EN_INIT()     GPIO_P3_SetMode(GPIO_Pin_6,GPIO_Mode_Output_PP);GPIO_SetSwitchSpeed(P3,GPIO_Pin_6,GPIO_SwitchSpeed_High);GPIO_SetPullUp(P3,GPIO_Pin_6,1)

#define MOTOR_DIR           P34
#define MOTOR_DIR_INIT()    GPIO_P3_SetMode(GPIO_Pin_4,GPIO_Mode_Output_PP);GPIO_SetSwitchSpeed(P3,GPIO_Pin_4,GPIO_SwitchSpeed_High);GPIO_SetPullUp(P3,GPIO_Pin_4,1)

//led macros
//#define DRV_LED             P36
//#define DRV_LED_INIT()      GPIO_P3_SetMode(GPIO_Pin_6,GPIO_Mode_Output_PP)

//ec11 macros
#define ENCODER_A           P12
#define ENCODER_A_INIT()    GPIO_P1_SetMode(GPIO_Pin_2,GPIO_Mode_InOut_QBD);GPIO_SetSwitchSpeed(P1,GPIO_Pin_2,GPIO_SwitchSpeed_High)

#define ENCODER_B           P11
#define ENCODER_B_INIT()    GPIO_P1_SetMode(GPIO_Pin_1,GPIO_Mode_InOut_QBD);GPIO_SetSwitchSpeed(P1,GPIO_Pin_1,GPIO_SwitchSpeed_High)

#define ENCODER_EN          P10
#define ENCODER_EN_INIT()   GPIO_P1_SetMode(GPIO_Pin_0,GPIO_Mode_InOut_QBD)

//uc1701 macros
#define SDA_H()             P23 =1     
#define SDA_L()             P23 =0  
#define SDA_INIT()          GPIO_P2_SetMode(GPIO_Pin_3,GPIO_Mode_Output_PP);GPIO_SetSwitchSpeed(P2,GPIO_Pin_3,GPIO_SwitchSpeed_High)
#define SDI                 P23

#define SCK_H()             P25 =1
#define SCK_L()             P25 =0
#define SCK_INIT()          GPIO_P2_SetMode(GPIO_Pin_5,GPIO_Mode_Output_PP);GPIO_SetSwitchSpeed(P2,GPIO_Pin_5,GPIO_SwitchSpeed_High)
#define SCL                 P25

#define RS_H()              P26 =1
#define RS_L()              P26 =0
#define RS_INIT()           GPIO_P2_SetMode(GPIO_Pin_6,GPIO_Mode_Output_PP);GPIO_SetSwitchSpeed(P2,GPIO_Pin_5,GPIO_SwitchSpeed_High)
#define RS                  P26

#define CS_H()              P00 =1
#define CS_L()              P00 =0
#define CS_INIT()           GPIO_P0_SetMode(GPIO_Pin_0,GPIO_Mode_Output_PP);GPIO_SetSwitchSpeed(P0,GPIO_Pin_0,GPIO_SwitchSpeed_High)
#define CS                  P00

#define RST_H()             P27 =1
#define RST_L()             P27 =0 
#define RST_INIT()          GPIO_P2_SetMode(GPIO_Pin_7,GPIO_Mode_Output_PP);GPIO_SetSwitchSpeed(P2,GPIO_Pin_7,GPIO_SwitchSpeed_High)
#define RES                 P27

#define COVER_R             P33
#define COVER_INIT()        GPIO_P3_SetMode(GPIO_Pin_3,GPIO_Mode_InOut_QBD)

#define CHA_FAN             P20
#define CHA_FAN_INIT()      GPIO_P2_SetMode(GPIO_Pin_0,GPIO_Mode_Output_PP)

#define DRY_FAN             P21
#define DRY_FAN_INIT()      GPIO_P2_SetMode(GPIO_Pin_1,GPIO_Mode_Output_PP)

#define LCD_BL              P22
#define LCD_BL_INIT()       GPIO_P2_SetMode(GPIO_Pin_2,GPIO_Mode_Output_PP)

#define UV_LED              P32
#define UV_LED_INIT()       GPIO_P3_SetMode(GPIO_Pin_2,GPIO_Mode_Output_PP)

#define BUZZER              P16
#define BUZZER_INIT()       GPIO_P1_SetMode(GPIO_Pin_6,GPIO_Mode_Output_PP)

typedef enum {ON = 0, OFF = !ON} OnOffStatus;
typedef enum {NORMAL = 0, INVERT = !NORMAL} InvertStatus;
typedef enum {scr_normal = 0,scr_CW= 1,scr_CCW= 2,scr_180= 3} ScrOrientation_TypeDef;
typedef enum {ENABLED = 0, DISABLED = !ENABLED} DisplayState;
typedef enum {PSet = 1,PReset = 0} PSetReset_TypeDef;
typedef enum {transparent= 0,opaque= 1} Opaque_TypeDef;

void debug_u32(uint32_t i);
void debug_i32(int32_t i);
void delay_nus(uint16_t nus);
void delay_nms(uint16_t nms);
void motor_init(void);
void motor_default(void);
void systick_init(void);
void encoder_ec11_scan(void);
uint8_t eeprom_read(uint8_t *dat,uint16_t addr, uint8_t _size);
uint8_t eeprom_write(uint8_t *dat,uint16_t addr, uint8_t _size);
#endif//__USERDEF_H__
